﻿Imports System.Xml.Serialization
Imports System.Reflection




Public Class ImprovedFlowpanel
    Inherits System.Windows.Forms.FlowLayoutPanel
    Public Property rwControlCollection As ControlCollection
    'Public Shadows Property controls As ControlCollection

    Protected Overrides Function CreateControlsInstance() As Control.ControlCollection
        rwControlCollection = MyBase.CreateControlsInstance()
        Return rwControlCollection
    End Function

    Public Sub addctrlblock(ByVal ctrllist As List(Of Control))
        Me.SuspendLayout()
        rwControlCollection.Clear()
        ctrllist.ForEach(Sub(x As Control)
                             rwControlCollection.Add(x)
                         End Sub)
        Me.ResumeLayout()
    End Sub


    Private Sub InitializeComponent()
        Me.SuspendLayout()
        Me.Name = "ImprovedFlowpanel"
        Me.ResumeLayout()

    End Sub
End Class




Public Class DiagnosticControl
    Inherits System.Windows.Forms.UserControl
    Public Const ValueptrWidth As Integer = 8
    Public Const CONlblspace As Integer = 4
    Dim Mathhelp As New MathHelp

#Region "Variables and Enumerations"
    Private mainPen As New Pen(Color.Black)
    Private privateBeadColor As System.Drawing.Color = Color.Black
    Private privatePenColor As System.Drawing.Color = Color.Black
    Private outlineColor As System.Drawing.Color = Color.Black
    Public Property valuebrush As System.Drawing.SolidBrush = CType(Brushes.DarkBlue, SolidBrush)
    Private mousevallabel As Graphics = Me.CreateGraphics
    'Test Properties
    Public Property testlocation As Point
    Public Property testlines As Point
    Public Property rotate As Int16
    Public Property rotateleft As Int16
    Public Property rotatebottom As Int16


    Protected Overrides ReadOnly Property DefaultSize As Size
        Get
            Return New Size(160, 30)
        End Get
    End Property


    Private noprogressbaravail As Boolean = True
    Private isClickable As Boolean = True
    'Private hasOutline As Boolean = True
    Private progbarvertoffset As Decimal = 2

    Public RecentVals(257) As Decimal
    Private orgheight As Integer = -10
    Private orgwidth As Integer = -10

    Private _drawchart As Boolean = False
    Private _storedhistory As Integer = -1
    Private Valrecordincrement As Integer = 0
    Private _valueShown As Object = 0
    Private _valuePixels As Integer
    Private _drawprogressbar As Boolean = False
    Private chartheight As Integer = 80
    Private DoProgressheight As Integer
    Private controlvalue As String
    Private hidevalue As Boolean = False


    Public ReadOnly Property storedhistory As Integer
        Get
            Return _storedhistory
        End Get
    End Property


#End Region

#Region "Control Properties"
    ' The color property of the beads
    Public Property BarColor As System.Drawing.Color = Color.Black
    Public Property MinColor As System.Drawing.Color = Color.Black
    Public Property MaxColor As System.Drawing.Color = Color.Black
    Public Property textbrush As System.Drawing.Brush = Brushes.Black
    Public Property minlabelWidth As Integer
    Public Property Clickable As Boolean

    Public Property drawchart As Boolean
        Get
            Return _drawchart
        End Get
        Set(value As Boolean)
            If _drawchart <> value Then
                Try
                    Me.ParentForm.Refresh()
                Catch
                    MsgBox("not open yet")
                End Try
            End If
            _drawchart = value
        End Set
    End Property




    Public Property DrawProgressbar As Boolean
        Get
            If noprogressbaravail = True Then
                progbarvertoffset = 2
                Return False
            Else

                Return _drawprogressbar
            End If

            'Return If(noprogressbaravail = True, False, _drawprogressbar)
        End Get

        Set(value As Boolean)
            progbarvertoffset = CDec(If((value = True And noprogressbaravail = False), 1.5, 2))
            _drawprogressbar = If((value = True And noprogressbaravail = False), True, False)
            Me.Invalidate()
        End Set
    End Property






    Public Property SetValue As Object
        Get
            Return _valueShown
        End Get
        Set(value As Object)
            Dim tdec As Decimal
            If Decimal.TryParse(CStr(value), tdec) Then
                _valueShown = tdec
                noprogressbaravail = False
                If storedhistory < 250 Then
                    _storedhistory = _storedhistory + 1
                End If

                Array.Copy(RecentVals, 0, RecentVals, 1, storedhistory)
                RecentVals(0) = CDec(_valueShown)
                controlvalue = CStr(_valueShown)
            Else
                _valueShown = value
                noprogressbaravail = True

                controlvalue = CStr(_valueShown)
            End If
            Me.Invalidate()

        End Set
    End Property









    Public Property RangeMin() As Decimal = 0
    Public Property RangeMax() As Decimal = 100

    Public Property labelcolor As System.Drawing.Color = Color.Black
    Public Property labelfont As System.Drawing.Font = New System.Drawing.Font("Microsoft Sans Serif", 9)

    Public Property ControlLabel As String
    Public Property ControlUnit As String
    Public Property ControlEndText As String

#End Region

    Public Sub Forcerefresh()
        Me.Invalidate()

    End Sub


#Region "Drawing Functions"
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        If orgheight = -10 Then
            orgheight = Me.Height
        End If

        If orgwidth = -10 Then
            orgwidth = Me.Width
        End If

        If drawchart = False Then
            Me.Width = orgwidth
            Me.Height = orgheight
            Me.BackColor = Nothing
            DoDrawBar(e)


        ElseIf drawchart = True Then
            Me.Width = 280
            Me.Height = 190
            DoDrawChart(e)
        End If
    End Sub
    Public Const DistanceFromLeft As Integer = 15
    Public Const Distancefrombottom As Integer = 20

    Private Sub DoDrawChart(e As System.Windows.Forms.PaintEventArgs)

        Dim rect As System.Drawing.Rectangle = e.ClipRectangle
        rect.Height = Me.Height
        'rect.widtth = Me.width

        Dim g As Graphics = e.Graphics
        g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
        'Me.BringToFront()
        Me.BackColor = Color.White
        Dim tpt1, tpt2, tpt3 As Point
        mainPen.Width = 2
        mainPen.Color = Color.DarkGray

        tpt1 = New Point(DistanceFromLeft, rect.Height - Distancefrombottom)
        tpt2 = New Point(rect.Width - 10, rect.Height - Distancefrombottom)
        tpt3 = New Point(DistanceFromLeft, 10)
        g.DrawLine(mainPen, tpt1, tpt2)
        g.DrawLine(mainPen, tpt1, tpt3)


        tpt1 = New Point(DistanceFromLeft, rect.Height - Distancefrombottom + 1)
        tpt2 = New Point(-38 + 0, -1 + 0)
        g.DrawString("Time", labelfont, textbrush, tpt1)

        g.RotateTransform(-90)
        g.DrawString("Value", labelfont, textbrush, tpt2)
        g.ResetTransform()


        Dim tparray(storedhistory) As PointF

        For I As Integer = 0 To storedhistory
            Dim X As Decimal = RecentVals(I)
            X = Mathhelp.LimitRange(X, RangeMax, RangeMin)
            Dim Vheightog As Decimal = rect.Height - ((((rect.Height - Distancefrombottom) / (RangeMax - RangeMin)) * X) + Distancefrombottom)
            Dim vwidth As Decimal = CDec(((rect.Width - DistanceFromLeft) - (((rect.Width - DistanceFromLeft) / 250) * I) + DistanceFromLeft))
            tparray(I) = New PointF(vwidth, Vheightog)
        Next
        If CBool(tparray.GetUpperBound(0)) Then
            mainPen.Color = Color.Black
            g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
            mainPen.Width = 3
            mainPen.LineJoin = Drawing2D.LineJoin.Round
            g.DrawLines(mainPen, tparray)
        End If

    End Sub


    Private Sub DoDrawBar(e As System.Windows.Forms.PaintEventArgs)
        Dim rect As System.Drawing.Rectangle = e.ClipRectangle
        Dim g As Graphics = e.Graphics
        g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
        Dim currXpos As Integer = 0
        Dim progbarlen As Integer = rect.Width
        Dim textsize As Integer






        ' Adjust the bead size depending on the chang in size of the control.
        mainPen.Width = CSng(System.Math.Ceiling(rect.Height / 100))
        mainPen.Width = 2

        progbarlen = CInt(progbarlen - g.MeasureString(ControlEndText, labelfont).Width())


        'Check for a starting label
        If ControlLabel IsNot Nothing Then
            mainPen.Color = Me.labelcolor
            textsize = CInt((rect.Height / 2) - (g.MeasureString(ControlLabel, labelfont).Height() / 2))
            g.DrawString(ControlLabel, labelfont, textbrush, currXpos, textsize)
            If g.MeasureString(ControlLabel, labelfont).Width < minlabelWidth Then
                currXpos = minlabelWidth
            Else
                currXpos = CInt(g.MeasureString(ControlLabel, labelfont).Width())
            End If
        End If

        textsize = 2

        If DrawProgressbar Then
            dbar(g, rect, currXpos, progbarlen)
        End If

        'show value
        If controlvalue IsNot Nothing And (hidevalue = False) Then
            g.DrawString(controlvalue, labelfont, textbrush, currXpos + textsize, ((rect.Height / progbarvertoffset) - (g.MeasureString(controlvalue, labelfont).Height() / 2)))
            textsize = CInt(textsize + g.MeasureString(controlvalue, labelfont).Width())

            '            currXpos = currXpos + g.MeasureString(Controlvalue, labelfont).Width()
        End If

        'Show Unit
        If ControlUnit IsNot Nothing Then
            g.DrawString(ControlUnit, labelfont, textbrush, currXpos + textsize, ((rect.Height / progbarvertoffset) - (g.MeasureString(ControlUnit, labelfont).Height() / 2)))
            textsize = CInt(textsize + g.MeasureString(ControlUnit, labelfont).Width())


        End If

        If DrawProgressbar Then
            currXpos = progbarlen
            textsize = 0
        End If

        'show End Text
        If ControlEndText IsNot Nothing Then
            g.DrawString(ControlEndText, labelfont, textbrush, currXpos + textsize, CDec(((rect.Height / 2) - (g.MeasureString(ControlEndText, labelfont).Height() / 2))))
            currXpos = CInt(currXpos + g.MeasureString(ControlEndText, labelfont).Width())
        End If


    End Sub


    Private Sub dbar(ByRef g As Graphics, ByVal rect As System.Drawing.Rectangle, currxpos As Integer, progbarlen As Integer)
        Dim textsize As Integer = 2
        g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
        currxpos = currxpos + CONlblspace

        'Start Drawing the Progress bar
        'Min Bar Color
        mainPen.Color = Me.MinColor
        g.DrawLine(mainPen, currxpos, 0, currxpos, rect.Height)
        'Main Bar
        mainPen.Color = Me.BarColor
        g.DrawLine(mainPen, currxpos, CInt(rect.Height / 3) + 1, progbarlen - 1, CInt(rect.Height / 3)) 'Down the Middle
        'Max Bar
        mainPen.Color = Me.MaxColor
        g.DrawLine(mainPen, CInt(progbarlen - 1), 0, CInt(progbarlen - 1), CInt(rect.Height))

        'Value Bar
        Try
            Dim valptrposition As Decimal = Mathhelp.LimitRange(CDec(SetValue), RangeMax, RangeMin)
            Dim unittopixel = ((progbarlen - currxpos) / (RangeMax - RangeMin)) * valptrposition
            Dim unitpt1 As New System.Drawing.PointF(CSng((unittopixel + currxpos) - (ValueptrWidth / 2)), 0)
            Dim unitpt2 As New System.Drawing.PointF(CSng((unittopixel + currxpos) + (ValueptrWidth / 2)), 0)
            Dim unitpt3 As New System.Drawing.PointF(unittopixel + currxpos, CInt(rect.Height / 3) + 2)
            Dim unitpt4 As New System.Drawing.PointF(unittopixel + currxpos, CInt(rect.Height / 3) + 4)
            Dim unitptlist As PointF() = {unitpt1, unitpt2, unitpt3}

            g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
            g.FillPolygon(valuebrush, unitptlist)
            Dim temppen As New Pen(valuebrush)
            g.DrawLine(temppen, unitpt3, unitpt4)
        Catch ex As Exception

        End Try

    End Sub




#End Region

#Region "Event Handlers"

    Protected Overrides Sub OnMouseLeave(e As EventArgs)
        If drawchart = True Then
            Dim hidebox As New Drawing.Rectangle With {.Location = New Point(0, 0), .Height = 0, .width = 0}
            mousevallabel.Clear(Color.Aquamarine)
            mousevallabel.SetClip(hidebox)
            Me.Invalidate()
        End If

        MyBase.OnMouseLeave(e)
    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
        If drawchart Then
            mousevallabel.CompositingMode = Drawing2D.CompositingMode.SourceOver
            Dim rect As New Drawing.Rectangle With {.Location = New Point(50, 0)}
            Dim tfont As New System.Drawing.Font("Microsoft Sans Serif", 9)

            Dim position0 As Decimal = Mathhelp.LimitRange(MousePosition.X - (ParentForm.Location.X + Me.Location.X + 9 + DistanceFromLeft), Me.Width - DistanceFromLeft, 0)
            Dim position As Integer = CInt(250 - (Math.Truncate((position0 / (Me.Width - DistanceFromLeft)) * 250)))
            Dim valdisplay As String = RecentVals(position).ToString

            If position0 > 1 Then
                rect.Height = 15
                rect.Width = 50
                mousevallabel.SetClip(rect)
                mousevallabel.Clear(Color.LightGray)
                mousevallabel.DrawString(valdisplay, labelfont, Brushes.Red, 50, 0)

            ElseIf Not mousevallabel.IsClipEmpty Then
                rect.Height = 0
                rect.Width = 0
                mousevallabel.SetClip(rect)
                Me.Invalidate()
            End If
        End If

        MyBase.OnMouseMove(e)
    End Sub





    Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
        If isClickable And DrawProgressbar = True Then
            If e.Button = Windows.Forms.MouseButtons.Left Then

                If drawchart = False Then
                    drawchart = True
                Else
                    drawchart = False
                End If
            Else
            End If
            Me.Invalidate()

        End If
    End Sub



#End Region

    Private Sub BeadedScoreBoard_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    End Sub
    Private Sub InitializeComponent()

        Me.SuspendLayout()
        Me.Name = "DiagnosticControl"
        Me.Width = 180
        Me.Height = 30
        Me.ResumeLayout(True)


    End Sub



    Public Sub New()



    End Sub
End Class


Public Class MathHelp
    Shared Function LimitRange(Test As Decimal, Ceil As Decimal, Flr As Decimal) As Decimal
        If Math.Min(Test, Flr) = Test Then
            Return Flr
        ElseIf Math.Max(Test, Ceil) = Test Then
            Return Ceil
        Else
            Return Test
        End If
    End Function
End Class